package ade.prime.activity;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;

import ade.prime.model.AdeWebOptions;
import ade.prime.model.Lesson;
import ade.prime.model.LessonHistory;
import ade.prime.model.LessonType;
import ade.prime.model.Lessons;
import ade.prime.model.Preferences;
import ade.prime.model.Schedule;
import ade.prime.service.AdeWebServiceApi;
import ade.prime.service.AdeWebServiceListener;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.SimpleOnPageChangeListener;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

/**
 * Vue affichant les informations d'un cours (détail d'un cours).
 *
 * @author Zanette Sébastien,
 * @author Andrianjafintrimo Victor
 */
public class LessonDetails extends AdeWebFragmentActivity 
implements BundleExtraNames, Preferences {
	
	@SuppressWarnings("hiding")
	protected static final String TAG = LessonDetails.class.getSimpleName() ;
	
	protected static final int REMOVE_LESSON_HISTORY = 1 ;
	
	protected static final int REMOVE_LESSON_HISTORY_DELAY = 5000 /* ms */ ;

	/**
	 * Conteneur d'information de ce cours.
	 */
	protected Lesson lesson;
	/**
	 * Index du cours courant dans la liste de cours.
	 */
	protected long idLesson;
	/**
	 * Liste complète des cours de l'emploi du temps.
	 */
	protected Lessons lessons;
	/**
	 * Boite de dialogue affichant un chargement lorsqu'un emploi du temps est
	 * mis à jour.
	 */
	protected ProgressDialog updateDialog;
	/**
	 * Ancienne instance du cours, utilisée pour montrer les changement lors
	 * d'un update
	 */
	protected Lesson oldS;

	protected MyAdapter mAdapter;

	protected ViewPager mPager;

	protected static Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			if (msg.what == REMOVE_LESSON_HISTORY) {
				UpdateMessageContent content = (UpdateMessageContent) msg.obj ;
//				Log.d(TAG, String.format("-- content.service: %s - content.lessonId: %s",
//						content.getServiceApi(), content.getLessonId())) ;
				try {
					content.getServiceApi().removeLessonHistory(
							content.getLessonId()) ;
				} catch (RemoteException re) {
					Log.d(TAG, String.format(
							"Failed to remove history for lesson %d", //$NON-NLS-1$
							Long.valueOf(content.getLessonId())), re) ;
				}// try
			} else {
				super.handleMessage(msg) ;
			}
		}
	} ;

	/**
	 * Initialise la vue.
	 * @param savedInstanceState 
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState) ;
		
		//Fixe le thème de la page
		this.setTheme(AdeWebOptions.getThemeAde(this)) ;
		//Ajoute une petite flèche à gauche du logo dans la barre d'action
		getSupportActionBar().setDisplayHomeAsUpEnabled(true);

		setContentView(R.layout.lesson_details);

		//Recupére la liste compléte des cours de l'emploi du temps passé en paramètre
		this.lessons = this.getIntentLessons();       
		//Positionne l'indice du cours courant
		this.idLesson = this.getIntent().getLongExtra(EXTRA_DISPLAYED_LESSON, 0) ;

		//Fixe le titre et le sous-titre de la barre d'action
		this.getSupportActionBar().setTitle(this.lessons.get(0).getTitle()) ;

		this.mAdapter = new MyAdapter(getSupportFragmentManager(), this.lessons) ;
		this.mPager = (ViewPager)findViewById(R.id.lesson_details_viewpager) ;
		this.mPager.setAdapter(this.mAdapter) ;    
		this.mPager.setOnPageChangeListener(new myPageChangeListener()) ;
		this.mPager.setPageMarginDrawable(R.drawable.grey_border_inset_lr);
		this.mPager.setPageMargin(getResources()
                 .getDimensionPixelSize(R.dimen.page_margin_width));
		this.lesson = this.lessons.get((int) this.idLesson) ;

		//Positionne le viewPager à la bonne page
		this.mPager.setCurrentItem((int) this.idLesson) ;
	}// onCreate(Bundle)

	/**
	 * {@inheritDoc}
	 * @see ade.prime.activity.AdeWebFragmentActivity#getAdeWebServiceListener()
	 */
	@Override
	protected AdeWebServiceListener getAdeWebServiceListener() {
		return new AdeWebServiceListenerAdapter(this) ;
	}// getAdeWebServiceListener()

	/**
	 * Remet à zéro après consultation du changement
	 */
	/*private void remisAZero(){
        Database db = new Database();
        db.updateStatutLesson(this.lesson.getLessonId(), this.lesson.getSchedule(), Lesson.NO_CHANGE);
        db.removeLesson_HistoryWithID(lesson.getLessonId(), lesson.getSchedule());
    }*/

	/**
	 * Affiche les boutons/options de la barre d'action.
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(R.string.ActionBar_mark)
		.setIcon(R.drawable.ic_action_edit_holo_dark)
		.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
		return super.onCreateOptionsMenu(menu);
	}

	/**
	 * Gére les actions des boutons/options de la barre d'action.
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch(item.getItemId()) {
		case android.R.id.home:
			try {
				Schedule schedule = this.serviceApi.getSchedule(
						this.lessons.get(0).getScheduleId()) ;
				Intent intent = NavUtils.getParentActivityIntent(this) ;
				intent.putExtra(EXTRA_SCHEDULE, schedule) ;
				NavUtils.navigateUpTo(this, intent);
			} catch(RemoteException re) {
				Log.d(TAG, "Failed to retrieve schedule", re) ; //$NON-NLS-1$
			}
            return true ;
			
		default:
			//Marque le cours (normal, important, examen)
			this.mark() ;
		}// switch
		return true ;
	}

	/**
	 * Affiche une boite de dialogue avec les choix de type de cours. Normal,
	 * Inmportant, Examen.
	 */
	private void mark() {
		LessonType currentType = this.lesson.getType() ;

		AlertDialog.Builder builder = new Builder(this) ;
		ListAdapter dialogAdapter = new ArrayAdapter<LessonType>(
				this, android.R.layout.select_dialog_singlechoice, LessonType.values()) ;
		builder.setSingleChoiceItems(dialogAdapter, currentType.ordinal(), 
				new MarkListener(this)) ;
		builder.setTitle(R.string.ViewSchedule_mark_dialog_title) ;
		builder.setIcon(RESULT_OK) ;
		builder.create().show() ;
	}// mark()

	/**
	 * Lorsqu'il y a eu un changement important dans, on récupére l'historique deu cours, et on met le flag 'changement' à vrai
	 */
	/* private void montrerChangement() {
        Database db = new Database();
        this.oldS = db.getLessonHistoryWithID(this.lesson.getLessonId(), this.lesson.getSchedule());
        this.changement = true;
    }*/

	/**
	 * OnClickListener pour le marquage d'un cour.
	 *
	 * <p>Récupère le type du cours ans met à jour la base de données.
	 *
	 * @author Schnell Michaël, Zanette Sébastien
	 */
	class MarkListener implements DialogInterface.OnClickListener {

		/**
		 * Vue contenant le composant attaché à l'écouteur.
		 */
		private LessonDetails activity;

		/**
		 * Constructeur.
		 *
		 * @param activity View containing the component attached to this
		 * listener
		 */
		public MarkListener(LessonDetails activity) {
			super();
			this.activity = activity;
		}// MarkListener(LessonDetails)

		/**
		 * Définition des action du clique sur le composant attaché.
		 *
		 * @param	actualView view of the component who has received a click
		 * event
		 */
		/*  public void onClick(DialogInterface dialog, LessonType item) {
            Lesson dispLesson = this.container.getLesson();
            // A new type has been selected
            if (item != dispLesson.getType()) {
                dispLesson.setType(item);
                Database db = new Database();
                db.updateLesson(dispLesson.getLessonId(), dispLesson.getSchedule(), dispLesson);
                this.container.init();
            }// if
            dialog.dismiss();
        }// onClick(View)*/

		@Override
		public void onClick(DialogInterface dialog, int which) {
			LessonType[] lessonTypes = LessonType.values() ;
			LessonType newType = lessonTypes[which] ;
			if (!newType.equals(this.activity.lesson.getType())) {
				try {
					this.activity.serviceApi.setLessonType(
							this.activity.lesson, newType) ;
				} catch (RemoteException re) {
					Log.d(TAG, String.format("Failed to mark lesson '%s' (%s)",  //$NON-NLS-1$
							this.activity.lesson.getTitle(), 
							Long.valueOf(this.activity.lesson.getLessonId())), re) ;
				}// try
			}// if

			dialog.dismiss() ;			
		}// onClick(DialogInterface, int)
	}// class MarkListener

	//	/**
	//	 * Retourne une instance de {@code Lesson} contenant l'information sur la
	//	 * lesson à afficher.
	//	 */
	//	private Lesson getIntentLesson() {
	//		long id = this.getIntent().getLongExtra(EXTRA_DISPLAYED_LESSON,0);
	//		return this.lessons.get((int)id);
	//	}// getIntentLesson()

	/**
	 * Retourne une instance de {@code Lessons} contenant tous les cours de l'emploi du temps.
	 */
	private Lessons getIntentLessons() {
		return this.getIntent().getParcelableExtra(EXTRA_SCHEDULE_LESSONS);
	}// getIntentLesson()

	/**
	 * Retourne une instance de {@code Lesson} contenant l'information sur la
	 * lesson à afficher.
	 *
	 * @return	instance of {@code Lesson} containing the information about the
	 * displayed lesson
	 */
	public Lesson getLesson() {
		return this.lesson;
	}// getLesson()


	/**
	 * Parse un {@code String} formaté de groupes et retourne une liste
	 * contenant tous les groupes.
	 *
	 * @param groups formatted {@code String} of groups
	 *
	 * @return	Array containing all the groups
	 */
	public static String[] parseGroups(String groups) {
		String[] g = groups.split(","); //$NON-NLS-1$
		if(g.length == 1 && g[0].equals("")){ //$NON-NLS-1$
			g = new String[0];
		}
		return g;
	}// parseGroup(String)

	/**
	 * Parse un {@code String} formaté d'enseignant et retourne une liste
	 * contenant tous les enseignants.
	 *
	 * @param teachers chaine de caractères d'enseignant séparés par des virgules
	 * @return	Array containing all the teachers
	 */
	public static String[] parseTeachers(String teachers) {
		String[] g = teachers.split(","); //$NON-NLS-1$
		if (g.length == 1 && TextUtils.isEmpty(g[0])){
			g = new String[0];
		}
		return g;
	}// parseTeachers(String)
	
	protected void sendUpdateMessage() {
		LessonDetails.handler.removeMessages(REMOVE_LESSON_HISTORY) ;
		if (this.lesson.getHistory() != null) {
			Message msg = LessonDetails.handler.obtainMessage(
					REMOVE_LESSON_HISTORY, new UpdateMessageContent(
							this.serviceApi, this.lesson.getLessonId())) ;
			LessonDetails.handler.sendMessageDelayed(msg, REMOVE_LESSON_HISTORY_DELAY) ;
		}
	}

	/**
	 * OnCancelListener pour le bouton "annuler", si l'utilisateur souhaite
	 * quitter cette vue pendant que l'emploi du temps est synchronisé.
	 *
	 * @author	Schnell Michaël, Zanette Sébastien
	 */
	class UpdateCancelListener extends Object implements OnCancelListener {

		/**
		 * Vue contenant le composant attaché à l'écouteur.
		 */
		protected LessonDetails container;

		/**
		 * Constructeur.
		 *
		 * @param container View containing the component attached to this
		 * listener
		 */
		public UpdateCancelListener(LessonDetails container) {
			super();
			this.container = container;
		}// UpdateCancelListener(LessonScreen)

		/**
		 * Définition l'action annuler.
		 *
		 * @param	actualView view of the component who has received a click
		 * event
		 */
		@Override
		public void onCancel(DialogInterface dialog) {
			dialog.dismiss();
			this.container.onBackPressed();
		}// onCancel(DialogInterface)
	}// class UpdateCancelListener

	public static class MyAdapter extends FragmentStatePagerAdapter {

		private Lessons lessons;

		public MyAdapter(FragmentManager fm, Lessons lessons) {
			super(fm);
			this.lessons = lessons;
		}

		@Override
		public int getCount() {
			return this.lessons.size();
		}

		@Override
		public Fragment getItem(int position) {
			return LessonFragment.newInstance(position, this.lessons) ;
		}
	}

	public static class LessonFragment extends SherlockFragment {
		int id;
		Lessons lessons;
		ViewGroup mRootView;
		public static final String DATE_FORMAT = "EEE dd MMM" ; //$NON-NLS-1$

		/**
		 * Create a new instance of ArrayListFragment, providing "num"
		 * as an argument.
		 */
		static LessonFragment newInstance(int id, Lessons lessons) {
			LessonFragment f = new LessonFragment();

			// Supply num input as an argument.
			Bundle args = new Bundle();
			args.putInt("id", id); //$NON-NLS-1$
			args.putParcelable("lessons", lessons); //$NON-NLS-1$
			f.setArguments(args);

			return f;
		}

		/**
		 * When creating, retrieve this instance's number from its arguments.
		 */
		@Override
		public void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			this.id = getArguments() != null ? getArguments().getInt("id") : 1; //$NON-NLS-1$
			this.lessons = getArguments().getParcelable("lessons"); //$NON-NLS-1$
		}

		/**
		 * The Fragment's UI is just a simple text view showing its
		 * instance id.
		 */
		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			Context context = inflater.getContext() ;
			this.mRootView = (ViewGroup) inflater.inflate(R.layout.lesson_details_pager_list, null);
			this.mRootView.setBackgroundColor(AdeWebOptions.getBackgroundColor(AdeWebOptions.getTheme(this.getActivity())));

			//On récupére le cours courant
			Lesson lesson = this.lessons.get(this.id);

			//Récupére les préférences de l'utilisateur
			boolean useColor = AdeWebOptions.useAdeWebColors(context) ;

			//On teste s'il faut afficher des changements importants dans la date ou les salles
			//TODO Gérer l'absence de salle
			String newRoom = lesson.getRoom() ;
			if (TextUtils.isEmpty(newRoom)) {
				newRoom = this.getActivity().getResources().getString(R.string.Lesson_room_unknown) ;
			}// if
			LessonHistory history = lesson.getHistory();
			String oldroom = ""; //$NON-NLS-1$
			if (history != null) {
				oldroom = history.getRooms();
			} else {
				oldroom = newRoom ;
			}// if

			//On initilise le header
			if (useColor) {
				LinearLayout layoutHeader = (LinearLayout)this.mRootView.findViewById(R.id.header_lesson);
				layoutHeader.setBackgroundColor(Color.parseColor(lesson.getColor()));
			}
			TextView titleHeader = (TextView)this.mRootView.findViewById(R.id.lesson_title);
			TextView subtitleHeader = (TextView)this.mRootView.findViewById(R.id.lesson_subtitle);			
			titleHeader.setText(lesson.getTitle());
			//TODO Remove hard coded message
			subtitleHeader.setText(String.format("%s de %s", //$NON-NLS-1$
					LessonFragment.displayDate(lesson.getDate()),
					LessonFragment.displayTime(lesson.getTime()))) ;


			//On ajoute les salles
			this.initRooms(inflater, newRoom, oldroom) ;

			//On ajoute les enseignants
			if (lesson.getTeacher().length() != 0) {
				for (String teacher : LessonFragment.parseTeachers(lesson.getTeacher())) {
					this.addTeacherItem(inflater, teacher);
				}
			} else {
				String noTeacherText = context.getResources()
						.getString(R.string.Lesson_teacher_unknown) ;
				this.addTeacherItem(inflater, noTeacherText);
			}

			//On ajoute les notes de cours (la section apparait uniquement s'il existe une note de cours)
			this.addNoteItem(lesson.getNote());

			//On ajoute les groupes
			if (lesson.getGroups().length() != 0) {
				this.addGroupItem(lesson.getGroups());
			}
			else {
				String noGroupText = context.getResources()
						.getString(R.string.Lesson_group_unknown) ;
				this.addGroupItem(noGroupText);
			}

			//On ajoute le reste dans la catégorie "plus" : date de création du cours, date de modification du cours
			this.addPlusItem(lesson.getCreated());

			return this.mRootView;
		}

		/**
		 * @deprecated On color le header maintenant
		 * @param inflater
		 * @param color
		 * @param activated
		 */
		@Deprecated
		public void addColorItem(LayoutInflater inflater, String color, boolean activated) {			
			ViewGroup colorsContainer = (ViewGroup) this.mRootView.findViewById(R.id.lesson_color_block);
			colorsContainer.removeAllViews();

			// Create the color item
			ViewGroup colorContainer = (ViewGroup) inflater.inflate(R.layout.lesson_details_bandeau_color, colorsContainer, false) ;
			TextView colorView = (TextView) colorContainer.findViewById(R.id.color);
			colorView.setBackgroundColor(Color.parseColor(color));

			colorsContainer.addView(colorContainer);
			colorsContainer.setVisibility(activated ? View.VISIBLE : View.GONE);
		}

		// TODO Si l'application vennait à être retravailler pour une version API lvl 14 minimum, 
		// il serait préférable d'appeller la fonction setVisibility(View.GONE) plutôt que de changer de layout
		public void addRoomItem(LayoutInflater inflater, String room, String oldroom) {
			ViewGroup roomsContainer = (ViewGroup) this.mRootView.findViewById(R.id.room_container) ;
			ViewGroup roomContainer ;
			TextView title ;
			//S'il n'y a pas de changement important de salle, alors on affiche pas de sous-titre
			if(oldroom.equals("")) { //$NON-NLS-1$
				// Create the room item
				roomContainer = (ViewGroup) inflater.inflate(R.layout.lesson_details_list_item_room, roomsContainer, false);
				title = ((TextView) roomContainer.findViewById(R.id.room_text)) ;
				title.setTextAppearance(this.getActivity(), R.style.newValueAdded);
			}
			else if(oldroom.equals(room)) {
				// Create the room item
				roomContainer = (ViewGroup) inflater.inflate(R.layout.lesson_details_list_item_room, roomsContainer, false);
				title = ((TextView) roomContainer.findViewById(R.id.room_text));
			}
			//Sinon on affiche en sous-titre l'ancienne valeur barrée
			else {
				// Create the room item
				roomContainer = (ViewGroup) inflater.inflate(R.layout.lesson_details_list_item_room2, roomsContainer, false);
				TextView subtitle = ((TextView) roomContainer.findViewById(R.id.room_subtext));
				subtitle.setText(oldroom);
				subtitle.setPaintFlags(subtitle.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); //on barre le texte
				title = ((TextView) roomContainer.findViewById(R.id.room_text));
			}
			title.setText(room);

			roomContainer.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View view) {
					// TODO
				}
			});

			roomsContainer.addView(roomContainer);
		}

		public void addTeacherItem(LayoutInflater inflater, String teacher) {
			ViewGroup teachersContainer = (ViewGroup) this.mRootView.findViewById(R.id.lesson_teacher_block);

			// Create the teacher item
			View teacherContainer = inflater.inflate(R.layout.teacher_detail, teachersContainer, false);
			((TextView) teacherContainer.findViewById(R.id.teacher_header)).setText(
					teacher);
			((TextView) teacherContainer.findViewById(R.id.teacher_abstract)).setVisibility(View.GONE);
			//((ImageView) teacherContainer.findViewById(R.id.teacher_image)).setContentDescription(contentDescription);

			teacherContainer.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View view) {
					// TODO
				}
			});

			teachersContainer.addView(teacherContainer);
		}

		public void addGroupItem(String group) {
			ViewGroup groupContainer = (ViewGroup) this.mRootView.findViewById(R.id.lesson_group_block);

			// Init the group item
			((TextView) groupContainer.findViewById(R.id.group_text)).setText(
					group);
		}

		public void addNoteItem(String note) {
			ViewGroup noteContainer = (ViewGroup) this.mRootView.findViewById(R.id.lesson_note_block);

			// Init the note item
			((TextView) noteContainer.findViewById(R.id.note_text)).setText(
					note);

			noteContainer.setVisibility(!note.equals("") ? View.VISIBLE : View.GONE); //$NON-NLS-1$
		}

		public void addPlusItem(String createdDate) {
			ViewGroup plusContainer = (ViewGroup) this.mRootView.findViewById(R.id.lesson_plus_block);

			// Init the plus item
			String plus = "Crée le : "+createdDate; //$NON-NLS-1$
			((TextView) plusContainer.findViewById(R.id.plus_text)).setText(plus);
		}

		public void initRooms(LayoutInflater inflater, String newValues, String oldValues){
			ArrayList<String> newList = new ArrayList<String>(Arrays.asList(parseRooms(newValues)));
			ArrayList<String> oldList = new ArrayList<String>(Arrays.asList(parseRooms(oldValues)));
			ArrayList<String> added = new ArrayList<String>();
			ArrayList<String> removed = new ArrayList<String>();
			ArrayList<String> unchanged = new ArrayList<String>();

			//On tri les 2 listes par ordre alphabétique
			Collections.sort(newList);
			Collections.sort(oldList);

			Iterator<String> oldIter = oldList.iterator() ;
			Iterator<String> newIter = newList.iterator() ;
			int i = 0, j = 0, nOld = oldList.size(), nNew = newList.size() ;
			while ((i < nOld) && (j < nNew)) {
				String oldRoom = oldList.get(i) ;
				String newRoom = newList.get(j) ;
				if (oldRoom.equals(newRoom)) {
					unchanged.add(oldRoom) ;
					i++ ; j++ ;
				} else if (oldRoom.compareTo(newRoom) < 0) {
					removed.add(oldRoom) ;
					i++ ;
				} else /* oldRoom.compareTo(newRoom) > 0 */ {
					added.add(newRoom) ;
					j++ ;
				}// if
			}// while
			for(; i < nOld; ++i) {
				removed.add(oldList.get(i)) ;
			}// for
			for(; j < nNew; ++j) {
				added.add(newList.get(j)) ;
			}// for
			
			//on affiche les salles inchangées
			for (String room : unchanged) {
				this.addRoomItem(inflater, room, room) ;
			}
			//on affiche les salles changées
			int nAdded = added.size();
			int nRemoved = removed.size();
			
//			Log.d(TAG, String.format("[initRooms]\n  old: %s\n  new: %s\n  added    : %s\n  removed  : %s\n  unchanged: %s\n",
//					oldList, newList, added, removed, unchanged)) ;
			
			oldIter = removed.iterator() ;
		    newIter = added.iterator() ;
			if (nAdded < nRemoved) { //Cas : le nbre d'elmts suppr est + grd que le nbre d'elmts ajoutés
				for(int c=1; c < nAdded; c++) {
					this.addRoomItem(inflater, newIter.next(), oldIter.next()) ;
					newIter.remove() ; 
					oldIter.remove() ;
				}// for
				this.addRoomItem(inflater, newIter.next(), TextUtils.join(", ", removed)) ; //$NON-NLS-1$
			}
			else { //Cas : le nbre d'elmts ajoutés est + grd que le nbre d'elmts suppr
				for(int c=0; c < nRemoved; c++) {
					this.addRoomItem(inflater, newIter.next(), oldIter.next()) ;
					newIter.remove() ; 
				}
				//on affiche les salles ajoutées
				for (String room : added) {
					this.addRoomItem(inflater, room, ""); //$NON-NLS-1$
				}
			}
		}

		/**
		 * Parse un {@code String} formaté de salles et retourne une liste
		 * contenant tous les salles.
		 *
		 * @param groups formatted {@code String} of groups
		 *
		 * @return	Array containing all the groups
		 */
		public static String[] parseRooms(String rooms) {
			String[] g = rooms.split(","); //$NON-NLS-1$
			if((g.length == 1) && (g[0].equals(""))){ //$NON-NLS-1$
				g = new String[0] ;
			}
			return g ;
		}// parseGroup(String)

		/**
		 * Parse un {@code String} formaté d'enseignant et retourne une liste
		 * contenant tous les enseignants.
		 *
		 * @param teachers chaine de caractères d'enseignant séparés par des virgules
		 * @return	Array containing all the teachers
		 */
		public static String[] parseTeachers(String teachers) {
			String[] g = teachers.split(","); //$NON-NLS-1$
			if(g.length == 1 && g[0].equals("")){ //$NON-NLS-1$
				g = new String[0];
			}
			return g;
		}// parseTeachers(String)

		public static String displayDate(Date date) {
			SimpleDateFormat dateFormater = 
					new SimpleDateFormat(DATE_FORMAT, Locale.FRANCE) ;
			String formattedDate = dateFormater.format(date) ;
			// Capitalize first letter
			formattedDate = String.format("%S%s", //$NON-NLS-1$
					formattedDate.substring(0, 1),
					formattedDate.substring(1)) ;					
			return formattedDate;
		}

		public static String displayTime(String date) {
			String heure = date;
			heure = heure.substring(heure.indexOf(" ")+1); //$NON-NLS-1$
			heure = heure.replace(':', 'h');
			heure = heure.replace('-', 'à');
			return heure;
		}
	}//LessonFragment

	private class myPageChangeListener extends SimpleOnPageChangeListener {
		protected myPageChangeListener() {
			super() ;
		}

		@Override
		public void onPageSelected(int position) {
			LessonDetails activity = LessonDetails.this ;
			activity.lesson = activity.lessons.get(position) ;
			activity.getSupportActionBar().setTitle(activity.lesson.getTitle()) ;
			
			activity.sendUpdateMessage() ;
		}
	}// class myPageChangeListener

	/**
	 * {@inheritDoc}
	 * @see ade.prime.activity.AdeWebFragmentActivity#getServiceConnection()
	 */
	@Override
	protected ServiceConnection getServiceConnection() {
		return new ServiceConnectionAdapter(this) ;
	}// getServiceConnection()

	private class ServiceConnectionAdapter 
	extends AdeWebFragmentActivity.ServiceConnectionAdapter {

		/**
		 * {@inheritDoc}
		 */
		protected ServiceConnectionAdapter(AdeWebFragmentActivity activity) {
			super(activity) ;
		}// ServiceConnectionAdapter(AdeWebFragmentActivity)

		/**
		 * {@inheritDoc}
		 */
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			super.onServiceConnected(name, service) ;
			// Ajout du sous-titre
			LessonDetails ld = (LessonDetails) this.activity ;
			int scheduleId = ld.lessons.get(0).getScheduleId() ;
			Schedule schedule = null ;
			try {
				schedule = ld.serviceApi.getSchedule(scheduleId) ;
				ld.getSupportActionBar().setSubtitle(schedule.getName()) ;
			} catch (RemoteException re) {
				Log.d(TAG, String.format(
						"Failed to retrieve schedule width id %d.",  //$NON-NLS-1$
						Integer.valueOf(scheduleId)), re) ;
			}// try
			ld.sendUpdateMessage() ;
		}// onServiceConnected(ComponentName, IBinder)

	}// class ServiceConnectionAdapter

	private class AdeWebServiceListenerAdapter 
	extends AdeWebFragmentActivity.AdeWebServiceListenerAdapter {
		protected AdeWebServiceListenerAdapter(AdeWebFragmentActivity activity) {
			super(activity) ;
		}// AdeWebServiceListenerAdapter(AdeWebFragmentActivity)
		/**
		 * {@inheritDoc}
		 */
		@Override
		protected void handleModifiedLessonTypeRunnable(Lesson modifiedLesson) {
			LessonDetails ld = (LessonDetails) this.activity ;
			long modifiedId = modifiedLesson.getLessonId() ;
			for(Lesson l : ld.lessons) {
				if (l.getLessonId() == modifiedId) {
					l.setType(modifiedLesson.getType()) ;
					break ;
				}// if
			}// for
			ld.mAdapter.notifyDataSetChanged() ;
		}// handleModifiedLessonTypeRunnable(Lesson)
		
		/**
		 * {@inheritDoc}
		 */
		@Override
		protected void handleRemovedLessonHistoryRunnable(long lessonId) {
			LessonDetails ld = (LessonDetails) this.activity ;
			for(Lesson l : ld.lessons) {
				if (l.getLessonId() == lessonId) {
//					Log.d(TAG, "Lesson found and history removed !") ;
					l.setHistory((LessonHistory) null) ;
					break ;
				}// if
			}// for
		}// handleRemovedLessonHistoryRunnable(long)
	}// class AdeWebServiceListenerAdapter
	
	private static class UpdateMessageContent {
		private AdeWebServiceApi serviceApi ;
		private long lessonId ;
		/**
		 * @param serviceApi
		 * @param lessonId
		 */
		public UpdateMessageContent(AdeWebServiceApi serviceApi, long lessonId) {
			super();
			this.serviceApi = serviceApi;
			this.lessonId = lessonId;
		}
		/**
		 * @return the serviceApi
		 */
		public AdeWebServiceApi getServiceApi() {
			return this.serviceApi;
		}
		/**
		 * @return the lessonId
		 */
		public long getLessonId() {
			return this.lessonId;
		}
	}

}// class LessenDetails
